// RegisterBox.cpp: implementation of the CRegisterBox class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "8085.h"
#include "RegisterBox.h"
#include "NumericBox.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

#define REGA		0
#define REGB		1
#define REGC		2
#define REGD		3
#define REGE		4
#define REGH		5
#define REGL		6

#define REGBC		7
#define REGDE		8
#define REGHL		9
#define REGIP		10
#define REGSP		11

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CRegisterBox::CRegisterBox()
{
    Init();    
}

CRegisterBox::~CRegisterBox()
{
    if(m_aNewValue!=NULL) delete [] m_aNewValue;
}


int CRegisterBox::RefreshStrings(int addr, BOOL bCheckModified)
{
    if(m_aDisplay==NULL) return 0;
    int nIndex=0;

    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s  %02X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;

    // register pairs
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s %04X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s %04X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s %04X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s %04X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s %04X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));
    nIndex++;

    //Display IP
    sprintf(m_aDisplay[nIndex].szMnemonic,"%s %04X",
        GetRegName(nIndex),m_aNewValue[nIndex]=GetRegValue(nIndex));

	int i;
	for(i=nIndex ; i<m_nItems ; i++)
		sprintf(m_aDisplay[i].szMnemonic," ");
	
    m_nItemsDisplayed = nIndex;

    for(i=0; i<nIndex ; i++)
    {
        if(bCheckModified)
        {
                if(m_aDisplay[i].data != m_aNewValue[i])
                    m_aDisplay[i].bModified = 1;
                else m_aDisplay[i].bModified = 0;
        }
        else m_aDisplay[i].bModified = 0;
        m_aDisplay[i].data = m_aNewValue[i];
    }
    return 1;
}

void CRegisterBox::SetIndividualProperty()
{
    m_aNewValue = new int[2*m_nItems];
}

void CRegisterBox::Init()
{
    m_aNewValue = NULL;
    SetMaxSize(m_nItems);
}

void CRegisterBox::EnterData()
{
    CNumericBox c;
    static char str[32];

    sprintf(str,"New value for register %s",GetRegName(m_nSelectedIndex));
    c.SetCaption(str);
    sprintf(str,"0x%02X",GetRegValue(m_nSelectedIndex));
    int nMax = m_nSelectedIndex>7 ? 0xffff : 0xff;
    int nResult;
    if(c.DisplayNumericBox(nResult,0,nMax,str))
    {
        SetRegValue(m_nSelectedIndex,nResult);
    }
	Refresh();
	if(m_nSelectedIndex == REGSP)
		// refresh the stack dump box
		GetParent()->PostMessage(ID_REFRESH_STACK_BOX,0,0);
	else if(m_nSelectedIndex  == REGIP)
		GetParent()->PostMessage(ID_REFRESH_INSTRUCTION_BOX,0,0);
}

// return the name register displayed at the 'nIndex' position in the register box
char * CRegisterBox::GetRegName(int nIndex)
{
    static char str[4];
    str[1] = '\0';

    switch(nIndex)
    {
    case REGA	: str[0]= 'A'; break;
    case REGB   : str[0]= 'B'; break;
    case REGC   : str[0]= 'C'; break;
    case REGD   : str[0]= 'D'; break;
    case REGE   : str[0]= 'E'; break;
    case REGH   : str[0]= 'H'; break;
    case REGL   : str[0]= 'L'; break;
    case REGBC  : sprintf(str,"BC"); break;
    case REGDE  : sprintf(str,"DE"); break;
    case REGHL  : sprintf(str,"HL"); break;
    case REGIP  : sprintf(str,"IP"); break;
    case REGSP  : sprintf(str,"SP"); break;
	default	  : str[0] = '\0';
    }
    return str;
}


word CRegisterBox::GetRegValue(int nIndex)
{
    word data;
    switch(nIndex)
    {
    case REGA : data=Get8085Object()->GetA();break;
    case REGB  : data=Get8085Object()->GetB();break;
    case REGC  : data=Get8085Object()->GetC();break;
    case REGD  : data=Get8085Object()->GetD();break;
    case REGE  : data=Get8085Object()->GetE();break;
    case REGH  : data=Get8085Object()->GetH();break;
    case REGL  : data=Get8085Object()->GetL();break;
    case REGBC : data=Get8085Object()->GetBC();break;
    case REGDE : data=Get8085Object()->GetDE();break;
    case REGHL : data=Get8085Object()->GetHL();break;
    case REGIP : data=Get8085Object()->GetIP();break;
    case REGSP : data=Get8085Object()->GetSP();break;
    }
    return data;
}

void CRegisterBox::SetRegValue(int nIndex, word data)
{
    switch(nIndex)
    {
    case REGA  : Get8085Object()->SetA((byte)data);break;
    case REGB   : Get8085Object()->SetB((byte)data);break;
    case REGC   : Get8085Object()->SetC((byte)data);break;
    case REGD   : Get8085Object()->SetD((byte)data);break;
    case REGE   : Get8085Object()->SetE((byte)data);break;
    case REGH   : Get8085Object()->SetH((byte)data);break;
    case REGL   : Get8085Object()->SetL((byte)data);break;
    case REGBC  : Get8085Object()->SetBC(data);break;
    case REGDE  : Get8085Object()->SetDE(data);break;
    case REGHL  : Get8085Object()->SetHL(data);break;
    case REGIP  : Get8085Object()->SetIP(data);break;
    case REGSP  : Get8085Object()->SetSP(data);break;
    }
}

void CRegisterBox::IncrementData()
{
    SetRegValue(m_nSelectedIndex,GetRegValue(m_nSelectedIndex)+1);
}

void CRegisterBox::DecrementData()
{
    SetRegValue(m_nSelectedIndex,GetRegValue(m_nSelectedIndex)-1);
}



